package Thread;

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;


/***
 *
 *Condition condition = lock.newCondition();
 * res. condition.await();  类似wait
 * res. Condition. Signal() 类似notify
 * Lock 接口与 synchronized 关键字的区别
 * Lock 接口可以尝试非阻塞地获取锁 当前线程尝试获取锁。如果这一时刻锁没有被其他线程获取到，则成功获取并持有锁。
 * Lock 接口能被中断地获取锁 与 synchronized 不同，获取到锁的线程能够响应中断，当获取到的锁的线程被中断时，中断异常将会被抛出，同时锁会被释放。
 * Lock 接口在指定的截止时间之前获取锁，如果截止时间到了依旧无法获取锁，则返回。
 * Condition用法
 *  Condition的功能类似于在传统的线程技术中的,Object.wait()和Object.notify()的功能。
 * **/
class Res {
    public String userName;
    public String sex;
    public boolean flag = false;
    Lock lock = new ReentrantLock();
}

class InputThread extends Thread {
    private Res res;
    Condition newCondition;
    public InputThread(Res res,	Condition newCondition) {
        this.res = res;
        this.newCondition=newCondition;
    }

    @Override
    public void run() {
        int count = 0;
        while (true) {
            // synchronized (res) {

            try {
                res.lock.lock();
                if (res.flag) {
                    try {
//						res.wait();
                        newCondition.await();
                    } catch (Exception e) {
                        // TODO: handle exception
                    }
                }
                if (count == 0) {
                    res.userName = "余胜军";
                    res.sex = "男";
                } else {
                    res.userName = "小红";
                    res.sex = "女";
                }
                count = (count + 1) % 2;
                res.flag = true;
//				res.notify();
                newCondition.signal();
            } catch (Exception e) {
                // TODO: handle exception
            }finally {
                res.lock.unlock();
            }
        }

        // }
    }
}

class OutThrad extends Thread {
    private Res res;
    private Condition newCondition;
    public OutThrad(Res res,Condition newCondition) {
        this.res = res;
        this.newCondition=newCondition;
    }

    @Override
    public void run() {
        while (true) {
//			synchronized (res) {
            try {
                res.lock.lock();
                if (!res.flag) {
                    try {
//						res.wait();
                        newCondition.await();
                    } catch (Exception e) {
                        // TODO: handle exception
                    }
                }
                System.out.println(res.userName + "," + res.sex);
                res.flag = false;
//				res.notify();
                newCondition.signal();
            } catch (Exception e) {
                // TODO: handle exception
            }finally {
                res.lock.unlock();
            }
//			}
        }

    }
}

public class ThreadLock {

    public static void main(String[] args) {
        Res res = new Res();
        Condition newCondition = res.lock.newCondition();
        InputThread inputThread = new InputThread(res,newCondition);
        OutThrad outThrad = new OutThrad(res,newCondition);
        inputThread.start();
        outThrad.start();
    }

}

